//
//  NumberKeyBoard.m
//  数字键盘
//
//  Created by Locke on 2016/10/20.
//  Copyright © 2016年 Locke. All rights reserved.
//

#import "NumberKeyBoard.h"
//#import "UIControl+Ignore.h"

typedef NS_ENUM(NSInteger, NumberKeyBoardButton) {
    NumberKeyBoardButtonMin,//最小值
    NumberKeyBoardButtonMax = NumberKeyBoardButtonMin + 10,//最大值
    NumberKeyBoardButtonNumber,
    NumberKeyBoardButtonMinus,//负号
    NumberKeyBoardButtonPoint,//点
    NumberKeyBoardButtonBackspace,//退格
    NumberKeyBoardButtonEmpty,//清空
    NumberKeyBoardButtonDone,//完成
    NumberKeyBoardButtonNone = NSNotFound
};

static const NSInteger NumberKeyBoardRows = 3;
static const NSInteger NumberkeyBoardColumns = 5;

@interface NumberKeyBoard ()
{
    NSMutableDictionary *_buttonDic;
    id <UIKeyInput> _keyInput;
    UILabel *_bigView;
}
@end

static __weak id currentFirstResponder;
@implementation UIResponder (FirstResponder)

+ (id)currentFirstResponder
{
    currentFirstResponder = nil;
    [[UIApplication sharedApplication] sendAction:@selector(findFirstResponder:) to:nil from:nil forEvent:nil];
    return currentFirstResponder;
}
- (void)findFirstResponder:(id)sender
{
    currentFirstResponder = self;
}

@end

@implementation NumberKeyBoard

- (instancetype) initWithFrame:(CGRect)frame {
    CGFloat width = CGRectGetWidth([UIScreen mainScreen].bounds);
    //UIInputViewStyleKeyboard 模仿背景键盘
    //self = [super initWithFrame:CGRectMake(0, 0, width, width / 3) inputViewStyle:UIInputViewStyleKeyboard];
    self = [super initWithFrame:CGRectMake(0, 0, width, width / 3)];
    if (self) {
        [self commonInit];
    }
    return self;
}

#pragma mark - 进行初始化
- (void)commonInit {
    //title数据
    NSArray *titleArray = @[@"1",@"2",@"3",@"-",@"退格",@"4",@"5",@"6",@"0",@"清空",@"7",@"8",@"9",@".",@"完成"];
    NSDictionary *titleDic = @{@"1":@(1),@"2":@(2),@"3":@(3),@"-":@(NumberKeyBoardButtonMinus),@"退格":@(NumberKeyBoardButtonBackspace),@"4":@(4),@"5":@(5),@"6":@(6),@"0":@(0),@"清空":@(NumberKeyBoardButtonEmpty),@"7":@7,@"8":@(8),@"9":@(9),@".":@(NumberKeyBoardButtonPoint),@"完成":@(NumberKeyBoardButtonDone)};
    //主背景色
    self.backgroundColor = [UIColor colorWithRed:121/255.0 green:121/255.0 blue:121/255.0 alpha:1.0];
    //数字字体大小
    UIFont *buttonNumFont = [UIFont systemFontOfSize:28.0f weight:UIFontWeightRegular];
    //文本字体大小
    UIFont *buttonTextFont = [UIFont systemFontOfSize:17.0f];
    //按钮文本颜色
    UIColor *buttonTiTleColor = [UIColor blackColor];
    //常态按钮背景色
    UIColor *buttonBgNormalColor = [UIColor whiteColor];
    //高亮按钮背景色
    UIColor *buttonBgSelectedColor = [UIColor colorWithRed:200/255.0 green:200/255.0 blue:212/255.0 alpha:1.0];
    //完成按钮的背景色
    UIColor *buttonDoneBgNormalColor = [UIColor colorWithRed:20/255.0 green:150/255.0 blue:241/255.0 alpha:1.0];
    //按钮宽高
    CGFloat buttonWidth = CGRectGetWidth(self.frame) / NumberkeyBoardColumns;
    CGFloat buttonHeight = CGRectGetHeight(self.frame) / NumberKeyBoardRows;
    //偏移量
    CGFloat offset = 0.5;
    
    _buttonDic = [NSMutableDictionary dictionary];
    
    for (int row = 0; row < NumberKeyBoardRows; row++) {
        for (int columns = 0; columns < NumberkeyBoardColumns; columns++) {
            UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(columns * buttonWidth, row * buttonHeight, buttonWidth - offset, buttonHeight - offset)];
            [button setTitleColor:buttonTiTleColor forState:UIControlStateNormal];
            [button setTitle:titleArray[row * NumberkeyBoardColumns + columns] forState:UIControlStateNormal];
            if (columns < NumberkeyBoardColumns - 1) {
                [button.titleLabel setFont:buttonNumFont];
                [button setBackgroundImage:[self imageWithColor:buttonBgNormalColor] forState:UIControlStateNormal];
                [button setBackgroundImage:[self imageWithColor:buttonBgSelectedColor] forState:UIControlStateHighlighted];
            } else {
                [button.titleLabel setFont:buttonTextFont];
                if ([button.titleLabel.text isEqualToString:@"完成"]) {
                    [button setBackgroundImage:[self imageWithColor:buttonDoneBgNormalColor] forState:UIControlStateNormal];
                    [button setBackgroundImage:[self imageWithColor:buttonBgNormalColor] forState:UIControlStateHighlighted];
                } else {
                    [button setBackgroundImage:[self imageWithColor:buttonBgSelectedColor] forState:UIControlStateNormal];
                    [button setBackgroundImage:[self imageWithColor:buttonBgNormalColor] forState:UIControlStateHighlighted];
                }
            }
            [_buttonDic setObject:button forKey:[titleDic valueForKey:button.titleLabel.text]];
            //            button.ignoreTime = 0.01;
            [button addTarget:self action:@selector(buttonTouchDown:withEvent:) forControlEvents:UIControlEventTouchDown];
            [button addTarget:self action:@selector(buttonDragInside:withEvent:) forControlEvents:UIControlEventTouchDragInside];
            [button addTarget:self action:@selector(buttonInput:withEvent:) forControlEvents:UIControlEventTouchUpInside];
            [self addSubview:button];
        }
    }
}

#pragma mark - 颜色转换为背景图片
- (UIImage *)imageWithColor:(UIColor *)color {
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return image;
}
#pragma mark - 
- (void)buttonTouchDown:(UIButton *)sender withEvent:(UIEvent *)event {
    if ([self isInButtonBounds:sender event:event] &&  _bigView == nil) {
        [self createAlertLabelWithButton:sender];
    }
}

#pragma mark - 判断移动问题，并弹框
- (void)buttonDragInside:(UIButton *)sender withEvent:(UIEvent *)event {
    if (![self isInButtonBounds:sender event:event]) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [_bigView removeFromSuperview];
            _bigView = nil;
        });
    }else if (_bigView == nil) {
        [self createAlertLabelWithButton:sender];
    }
}

#pragma mark - 判断触点位置
- (BOOL)isInButtonBounds:(UIButton *)button event:(UIEvent *)event {
    UITouch *touch = [[event allTouches] anyObject];
    CGFloat boundsExtension = 0.0f; //扩展范围阀值
    CGRect outerBounds = CGRectInset(button.bounds, -1 * boundsExtension, -1 * boundsExtension);
    BOOL touchOutside = !CGRectContainsPoint(outerBounds, [touch locationInView:button]);
    if (touchOutside) {
        BOOL previewTouchInside = CGRectContainsPoint(outerBounds, [touch previousLocationInView:button]);
        if (previewTouchInside) {
            // UIControlEventTouchDragExit
        } else {
            // UIControlEventTouchDragOutside
        }
        return NO;
    } else {
        BOOL previewTouchOutside = !CGRectContainsPoint(outerBounds, [touch previousLocationInView:button]);
        if (previewTouchOutside) {
            // UIControlEventTouchDragEnter
        } else {
            // UIControlEventTouchDragInside
        }
        return YES;
    }
}

- (void)createAlertLabelWithButton:(UIButton *)sender {
    CGFloat offset = 5;
    CGFloat b_width = 80;
    CGFloat b_height = 80;
    
    CGPoint b_center = sender.center;
    CGFloat b_centerx = (b_center.x > b_width/2)?(b_center.x):(b_width/2);
    UIColor *color = [UIColor colorWithRed:106/255.0 green:200/255.0 blue:250/255.0 alpha:1.0];
    if(b_center.x < b_width/2) {
        b_centerx = b_width/2;
    } else if(b_center.x > CGRectGetWidth(self.frame) - b_width/2) {
        b_centerx = CGRectGetWidth(self.frame) - b_width/2;
    } else {
        b_centerx = b_center.x;
    }
    CGFloat b_centery = CGRectGetHeight([UIScreen mainScreen].bounds ) - (CGRectGetHeight(self.frame) - CGRectGetMinY(sender.frame)  + b_height / 2 + offset);
    _bigView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, b_width, b_height)];
    _bigView.center = CGPointMake(b_centerx, b_centery);
    _bigView.text = sender.titleLabel.text;
    if (sender.titleLabel.text.length > 1) {
        _bigView.font = [UIFont systemFontOfSize:20];
    } else {
        _bigView.font = [UIFont systemFontOfSize:30];
    }
    _bigView.textAlignment = NSTextAlignmentCenter;
    _bigView.backgroundColor = [UIColor whiteColor];
    _bigView.textColor = color;
    _bigView.layer.borderColor = [color CGColor];
    _bigView.layer.borderWidth = 1.0;
    [[[UIApplication sharedApplication].windows lastObject] addSubview:_bigView];
}

#pragma mark - 计算
- (void)buttonInput:(UIButton *)sender withEvent:(UIEvent *)event {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [_bigView removeFromSuperview];
        _bigView = nil;
    });
    if (![self isInButtonBounds:sender event:event]) {
        return;
    }
    __block NumberKeyBoardButton keyboardButton = NumberKeyBoardButtonNone;
    [_buttonDic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        if (sender == obj) {
            keyboardButton = [key integerValue];
            *stop = YES;
        }
    }];
    
    if (keyboardButton == NumberKeyBoardButtonNone) {
        return;
    }
    
    id <UIKeyInput> keyInput = self.keyInput;
    
    if (!keyInput) {
        return;
    }
    UITextField *textField = (UITextField *)keyInput;
    
    //纯数字键盘
    if (textField.keyboardType == UIKeyboardTypeNumberPad && (keyboardButton == NumberKeyBoardButtonMinus || keyboardButton == NumberKeyBoardButtonPoint)) {
        return;
    }
    //一个小数点的数字
    if (textField.keyboardType == UIKeyboardTypeDecimalPad && keyboardButton == NumberKeyBoardButtonMinus) {
        return;
    }
    //数字和分类标点符号键盘
    if (textField.keyboardType == UIKeyboardTypeNumbersAndPunctuation) {
        
    }
    
    if ([textField.delegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) {
        if (![textField.delegate textField:textField shouldChangeCharactersInRange:[self selectedRange:textField] replacementString:[sender titleForState:UIControlStateNormal]]) {
            return;
        }
    }
    
    
    
    //输入数字
    if (keyboardButton >= NumberKeyBoardButtonMin && keyboardButton < NumberKeyBoardButtonMax) {
        NSNumber *number = @(keyboardButton);
        NSString *numberString = number.stringValue;
        UITextField *textField = (UITextField *)keyInput;
        if(textField.keyboardType == UIKeyboardTypeNumberPad) {
            [keyInput insertText:numberString];
        } else {
            if (textField.text.length == 1 && [textField.text isEqualToString:@"0"]) {
                return;
            } else if(textField.text.length == 2 && [textField.text isEqualToString:@"-0"]) {
                return;
            } else {
                [keyInput insertText:numberString];
            }
        }
    }
    //输入负号
    else if(keyboardButton == NumberKeyBoardButtonMinus) {
        NSString *minusString = [sender titleForState:UIControlStateNormal];
        if ([textField.text rangeOfString:minusString].location == NSNotFound && !textField.text.length) {
            [keyInput insertText:minusString];
        } else {
            return;
        }
    }
    //输入点
    else if(keyboardButton == NumberKeyBoardButtonPoint) {
        NSString *minusString = [sender titleForState:UIControlStateNormal];
        if ([textField.text rangeOfString:minusString].location == NSNotFound && textField.text.length && ![[textField.text substringFromIndex:(textField.text.length - 1)] isEqualToString:@"-"]) {
            [keyInput insertText:minusString];
        } else {
            return;
        }
    }
    //退格
    else if(keyboardButton == NumberKeyBoardButtonBackspace) {
        if (textField.text.length) {
            [keyInput deleteBackward];
        } else {
            return;
        }
    }
    //清空
    else if(keyboardButton == NumberKeyBoardButtonEmpty) {
        if ([textField.delegate respondsToSelector:@selector(textFieldShouldClear:)]) {
            if (![textField.delegate textFieldShouldClear:textField]) {
                return;
            }
        }
        [self setSelectedRange:textField];
        if (textField.text.length) {
            NSInteger length = textField.text.length;
            while (length--) {
                [keyInput deleteBackward];
            }
        } else {
            return;
        }
    }
    //完成
    else if(keyboardButton == NumberKeyBoardButtonDone) {
        if ([textField.delegate respondsToSelector:@selector(textFieldShouldReturn:)]) {
            if (![textField.delegate textFieldShouldReturn:textField]) {
                return;
            }
        }
        if (![textField.text floatValue]) {
            NSInteger length = textField.text.length;
            while (length--) {
                [keyInput deleteBackward];
            }
            [keyInput insertText:@"0"];
        }else if ([[textField.text substringFromIndex:(textField.text.length - 1)] isEqualToString:@"."]) {
            [keyInput deleteBackward];
        }
        [self dismissKeyBoard];
    }
}
#pragma mark - 光标位置
- (NSRange)selectedRange:(UITextField *)textfield {
    UITextPosition *beginning = textfield.beginningOfDocument;
    
    UITextRange *selectedRange = textfield.selectedTextRange;
    UITextPosition *selectionStart = selectedRange.start;
    UITextPosition *selectionEnd = selectedRange.end;
    
    const NSInteger location = [textfield offsetFromPosition:beginning toPosition:selectionStart];
    const NSInteger length = [textfield offsetFromPosition:selectionStart toPosition:selectionEnd];
    
    return NSMakeRange(location, length);
}
- (void)setSelectedRange:(UITextField *)textfield{
    UITextPosition *beginning = textfield.beginningOfDocument;
    
    UITextPosition *startPosition = [textfield positionFromPosition:beginning offset:textfield.text.length];
    UITextPosition *endPosition = [textfield positionFromPosition:beginning offset:textfield.text.length];
    UITextRange *selectionRange = [textfield textRangeFromPosition:startPosition toPosition:endPosition];
    
    [textfield setSelectedTextRange:selectionRange];
}


- (id<UIKeyInput>)keyInput
{
    id <UIKeyInput> keyInput = _keyInput;
    
    keyInput = [UIResponder currentFirstResponder];
    
    if (keyInput != _keyInput) {
        //        [self resetZeroData:keyInput];
    }
    
    if (![keyInput conformsToProtocol:@protocol(UITextInput)]) {
        NSLog(@"Warning: First responder %@ does not conform to the UIKeyInput protocol.", keyInput);
        return nil;
    }
    
    _keyInput = keyInput;
    
    return keyInput;
}
#pragma mark - 隐藏键盘
- (void)dismissKeyBoard {
    UIResponder *firstResponder = (UIResponder *)self.keyInput;
    if (firstResponder) {
        [firstResponder resignFirstResponder];
    }
}
#pragma mark - 清零操作
- (void)resetZeroData:(id <UIKeyInput>)keyInput {
    //清零操作
    UITextField *textField = (UITextField *)keyInput;
    if (textField.text.length == 1 && ![textField.text floatValue]) {
        [keyInput deleteBackward];
    }
}

#pragma mark - 绘制方格
- (void)drawRect:(CGRect)rect {
    [self boundBox];
}

- (void)boundBox {
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(contextRef, [[UIColor lightGrayColor] CGColor]);
    //    CGContextSetRGBStrokeColor(contextRef, 50/255.0, 180/255.0, 30/255.0,1);
    CGFloat buttonWidth = CGRectGetWidth(self.frame) / NumberkeyBoardColumns;
    CGFloat buttonHeight = CGRectGetHeight(self.frame) / NumberKeyBoardRows;
    CGContextSetLineWidth(contextRef, 0.5);
    CGContextBeginPath(contextRef);
    CGContextMoveToPoint(contextRef, 0, 0);
    for (int row = 0; row < NumberKeyBoardRows; row++) {
        CGContextMoveToPoint(contextRef, 0, row * buttonHeight);
        CGContextAddLineToPoint(contextRef, CGRectGetWidth(self.frame), row * buttonHeight);
    }
    for (int columns = 0; columns < NumberkeyBoardColumns; columns++) {
        CGContextMoveToPoint(contextRef, columns * buttonWidth, 0);
        CGContextAddLineToPoint(contextRef, columns * buttonWidth, CGRectGetHeight(self.frame));
    }
    CGContextStrokePath(contextRef);
}

@end
